Skip to content
created by Aha00aAha00a at 2026-08-10
last modified by Aha00aAha00a at 2026-08-10
revision: 2

Dev ApiControllers

/api 아래 endpoint 를 어느 컨트롤러가 갖는지, 그리고 왜 그렇게 나눴는지.

1. 경계

나누는 기준은 **누가 부르는가** 다. 파일 크기가 아니다.

컨트롤러

무엇을 갖는가

Api

위키 자신이 부르는 것 — 현재 사용자, CSRF 토큰, 페이지 이름·미리보기, 링크, 편집기 자동완성 목록, 전체 통계

ApiAdminSite

**한 사이트를 바꾸는 것** — 사이트 레코드, 권한, 사이트 관리자, favicon·테마·텔레그램, 페이지 메타, 캐시 재계산

ApiAdminReport

**여러 사이트를 걸쳐 읽는 것** — 사용자 목록, 조회 이력, 일별 통계, 인기 페이지, 최근 변경, 접근 로그

ApiAdminS3

버킷 브라우저 — 목록·삭제·다운로드 URL

ApiApiKey

API Key — 사용자가 자기 것을 관리하는 쪽과 관리자가 회수하는 쪽

ApiV1

Bearer 인증 외부 API. Api 참고

ApiCrawler

외부 URL 크롤링과 그 캐시

위키 페이지 자체를 다루는 컨트롤러도 같은 기준으로 나뉘어 있습니다.

컨트롤러

무엇을 갖는가

Wiki

페이지를 읽고 쓰는 것 — view, save, delete, rename, preview 와 렌더링·권한 요약 헬퍼

WikiAttachment

첨부 — 업로드·목록·삭제·클립보드 붙여넣기. S3 에 바이트를 넣는 쪽

WikiRealtime

페이지 WebSocket — 누가 보고 있는지, 커서 위치, 저장 알림

WikiSpreadsheet

Google Spreadsheet 를 표로 끌어오는 것. 남의 서비스와의 연동

Wiki 에서 렌더링 헬퍼가 나가지 않은 이유는 view 와 preview 가 같은 방식으로 렌더링하기 때문이고, 권한 헬퍼가 남은 이유는 view 가 요약을 보여주고 save 가 그것을 적용하기 때문입니다.

save 는 여전히 logics.PageCursorHub 를 호출해 변경을 알립니다. 이 hub 는 WebSocket 이 소유한 것이 아니라 **공유하는 것** 이라, 둘이 떨어져도 각자 절반의 구독자만 갖는 일이 생기지 않습니다.

ApiAdminSite 의 endpoint 는 전부 site seq 로 범위가 정해지고 withSiteAdmin 또는 withAdminSite 를 지납니다. 그 둘이 **권한을 먼저 보고 그 다음에 site 를 조회** 하는 순서를 쥐고 있어서, 순서가 갈라지지 않도록 한 곳에 모았습니다. 자세한 이유는 Dev ApiResponse 참고.

ApiAdminReport 는 읽기 전용 질의만 있습니다. 느려질 가능성이 가장 큰 endpoint 들이라, 한 파일에 모으면 어디를 봐야 하는지가 드러납니다.

2. 예외 둘

Api 에 관리자용 endpoint 두 개가 남아 있습니다. 이유가 있습니다.

  • adminGenerateSignedReadUrl — 사이트가 아니라 **페이지** 에 대한 것입니다. 사이트 관리와 성격이 다릅니다.
  • adminMemoryCacheStats — 이 값을 쓰는 주기 작업이 Api 생성자에 등록돼 있습니다. 같은 캐시 키를 쓰는 **읽는 쪽과 쓰는 쪽** 이라 떨어뜨리면 키가 갈라집니다.

3. 나눌 때 지킨 것

  • 라우트만 바꾸고 endpoint 의 동작은 건드리지 않았습니다.
  • 옮긴 뒤 conf/routes 의 모든 참조가 실재하는 컨트롤러·메서드를 가리키는지 기계로 확인했습니다. 라우트는 문자열이라 오타가 컴파일에 걸리지 않습니다.
  • 여러 컨트롤러가 함께 쓰는 것은 트레이트로 갑니다 — JsonResults, AdminAuth. 컨트롤러를 나누면 헬퍼를 복사하고 싶어지는데, 그 순간이 사본이 둘이 되는 순간입니다.

4. See Also

4.2. Similar Pages

Similar pages by cosine similarity. Words after page name are term frequency.

  • 54.34% Dev Api api(18:129), key(2:66), page(1:27), admin(10:15), wiki(5:17), v1(1:13), 목록(2:8), 페이지(6:4), seq(1:8), 인증(1:7)
  • 52.62% Api api(18:85), key(2:32), page(1:29), 페이지(6:19), wiki(5:15), v1(1:15), 저장(1:15), 조회(2:11), admin(10:3), bearer(1:11)
  • 51.30% Dev ApiResponse api(18:33), admin(10:26), site(6:29), json(1:32), 아니라(2:7), crawler(1:7), wiki(5:3), with(2:6), endpoint(5:3), conf(1:7)
  • 45.44% ToDo ApiKey api(18:29), key(2:9), page(1:8), 페이지(6:3), wiki(5:2), 저장(1:4), 같은(3:2), controllers(1:3), 사이트(3:1), 권한(2:2)
  • 42.04% Dev AdminUIRoleMenu admin(10:13), api(18:5), site(6:12), 페이지(6:1), wiki(5:1), seq(1:4), 접근(1:3), 사이트(3:1), cache(1:2), 전체(1:2)
  • 35.01% Dev SiteAdmin admin(10:16), site(6:19), api(18:1), seq(1:4), 사이트(3:2), 기준으로(1:2), dev(2:1), controllers(1:1), logics(1:1), 권한을(1:1)

4.3. Adjacent Pages

Control
≤ 32
all
1.0x
1.0x
80
-120
ON
Metrics
Nodes(visible/total)0/0
Links(visible/total)0/0
Avg degree0.00
Depth coverage0
Queue(fetch/graph)0 / 0
Zoom(scale)1.00x
Ctrl/⌘ + Scroll: Zoom
Root 1-hop 2-hop+